﻿namespace UFIDA.U9.Cust.SH.SHFastShipBP
{
	using System;
	using System.Collections.Generic;
	using System.Text; 
	using UFSoft.UBF.AopFrame;	
	using UFSoft.UBF.Util.Context;
    using UFIDA.U9.Base;
    using UFIDA.U9.CBO.SCM.Customer;
    using System.Data;
    using UFSoft.UBF.Util.DataAccess;
    using UFSoft.UBF.PL;
    using UFIDA.U9.CBO.SCM.Item;
    using UFSoft.UBF.Sys.Database;
    using UFIDA.U9.Cust.SH.SHFastShipBP.SHFastShipBP;

	/// <summary>
	/// GetPrice partial 
	/// </summary>	
	public partial class GetPrice 
	{	
		internal BaseStrategy Select()
		{
			return new GetPriceImpementStrategy();	
		}		
	}
	
	#region  implement strategy	
	/// <summary>
	/// Impement Implement
	/// 
	/// </summary>	
	internal partial class GetPriceImpementStrategy : BaseStrategy
	{
		public GetPriceImpementStrategy() { }

		public override object Do(object obj)
		{						
			GetPrice bpObj = (GetPrice)obj;
			
			//get business operation context is as follows
			//IContext context = ContextManager.Context	
			
			//auto generating code end,underside is user custom code
			//and if you Implement replace this Exception Code...
			//throw new NotImplementedException();
            if (bpObj.ItemIDS.Count <= 0) throw new Exception("料品为空！");
            if (bpObj.CustomerID <= 0) throw new Exception("客户为空！");

            Customer cu = Customer.Finder.FindByID(bpObj.CustomerID);
            if (cu == null) throw new Exception("客户查找失败！");

            DataTable dtPriceNeedSetRecords = null;
            long saleAgentOrgID = 0;
            List<PriceDTO> retlist = new List<PriceDTO>();
            List<string> ItemCodes = new List<string>();
            foreach (long id in bpObj.ItemIDS)
            {
                ItemMaster item = ItemMaster.Finder.FindByID(id);
                if (item == null) throw new Exception("料品查找失败！");
                if (item.PriceCategoryKey == null) throw new Exception("料品"+item.Name+"不存在价格分类，请维护！");

                PriceDTO dto = new PriceDTO();
                dto.CustomerID = cu.ID;
                dto.ItemID = item.ID;
                dto.ItemCode = item.Code;

                retlist.Add(dto);
                ItemCodes.Add(item.Code);
            }

            if (Context.LoginOrg.Code == "1000")
            {
                //双虎组织

                //下线客户,取总经销客户价格
                if (cu.DescFlexField.PrivateDescSeg8 == "True")
                {
                    string cucode = cu.CustomerCategory.DescFlexField.PrivateDescSeg1;
                    cu = Customer.Finder.Find("Org="+Context.LoginOrg.ID+" and Code='"+cucode+"'");
                    if (cu == null) throw new Exception("查找客户对应总经销失败，总经销编码："+cucode);
                }

                if (cu.DefaultContactKey == null)
                {
                    throw new Exception(string.Format("客户【{0}】未设置联系对象", cu.Name));
                }

                if (cu.PriceListID <= 0)
                {
                    throw new Exception(string.Format("当前客户【{0}】未设置销售价目表", cu.Name));
                }

                ////取客户联系对象与经销商联系对象一致的经销商
                //UFIDA.U9.Cust.JS.ShuangHu.RetailBE.CBOStoresBE.SalesAgent _SaleAgent = UFIDA.U9.Cust.JS.ShuangHu.RetailBE.CBOStoresBE.SalesAgent.Finder.Find("Contaction=@ID", new OqlParam(cu.DefaultContactKey.ID));
                //if (_SaleAgent == null)
                //{
                //    throw new Exception(string.Format("未找到当前客户【{0}】对应的经销商，请检查客户联系对象是否已关联", cu.Name));
                //}
                //saleAgentOrgID = _SaleAgent.OrgKey.ID;
                ////价表取价，取产品费、品牌费
                //dtPriceNeedSetRecords = GetItemPriceByNeedSetPriceRecords(bpObj.ItemIDS,cu.PriceListID
                //    ,DateTime.Now,cu.ID);
            }
            else
            {
                //总代组织
                saleAgentOrgID = Context.LoginOrg.ID;
                //价表取价，取产品费、品牌费
                //dtPriceNeedSetRecords = GetItemPriceByNeedSetPriceRecords(saleAgentOrgID, 0, Context.LoginDate, bpObj.ItemIDS);
                //修改取价规则2012-5-24
                dtPriceNeedSetRecords = GetItemPriceByNeedSetPriceRecords1(saleAgentOrgID,ref cu, DateTime.Now
                    , bpObj.ItemIDS);
            }

            string pricelistid="";
            if (dtPriceNeedSetRecords != null && dtPriceNeedSetRecords.Rows.Count > 0)
                pricelistid = dtPriceNeedSetRecords.Rows[0]["双虎价表"].ToString();
            else
            {
                ItemMaster item=ItemMaster.Finder.FindByID(bpObj.ItemIDS[0]);
                throw new Exception("查找客户价表失败，客户："+cu.Name+" 料品："+item.Name);
            }
            //批量获取费用规则相关信息
            DataTable dtRuleInfos = GetFeeRuleByNeedSetPriceRecords(saleAgentOrgID.ToString(), ItemCodes, pricelistid);

            //计算订单行费用根据费用规则
            CalacFeePriceByFeeRule(retlist, dtRuleInfos, saleAgentOrgID, dtPriceNeedSetRecords, bpObj.CustomerID);

            return retlist;
		}
        
        /// <summary>
        /// 计算订单行的费用（产品费、品牌费、物流费）根据费用规则
        /// </summary>
        private void CalacFeePriceByFeeRule(List<PriceDTO> retlist, DataTable dtRuleInfos
            , long saleAgentOrgID, DataTable dtPriceNeedSetRecords,long custid)
        {
            Customer cu = Customer.Finder.FindByID(custid);
            if (cu == null)
            {
                throw new Exception("查找客户失败!");
            }

            foreach (PriceDTO dto in retlist)
            {
                DataRow[] drRuleLineInfo = null;
                DataRow[] drPrice = null;

                if (dtRuleInfos != null && dtRuleInfos.Rows.Count > 0)
                {
                    drRuleLineInfo = dtRuleInfos.Select(string.Format("ItemCode='{0}'", dto.ItemCode));
                }

                if (drRuleLineInfo == null|| drRuleLineInfo.Length<=0)
                {
                    throw new Exception(string.Format("料品【{0}】在费用规则中未设置料品价格分类，无法获取到仓储费和物流费！", dto.ItemCode));
                }

                if (dtPriceNeedSetRecords != null && dtPriceNeedSetRecords.Rows.Count > 0)
                {
                    //优先获取本客户价表行
                    drPrice = dtPriceNeedSetRecords.Select(string.Format("料号='{0}'", dto.ItemCode), "客户ID desc");
                }

                if (drPrice == null || drPrice.Length <= 0)
                {
                    throw new Exception(string.Format("料品【{0}】没有价表，无法获取到产品费和品牌费！", dto.ItemCode));
                }

                #region 产品费处理
                dto.ProductCost = PubTool.ToDecimal(drPrice[0]["销售价格"].ToString());
                dto.PriceType = (drPrice[0]["正特价"].ToString() == "" || drPrice[0]["正特价"].ToString() == "0") ? "0" : "1";
                #endregion

                #region 品牌费处理
                decimal brandFee = PubTool.ToDecimal(drPrice[0]["品牌费"].ToString());
                dto.MarkCost = brandFee;
                #endregion

                #region 物流费处理
                decimal ShipFeeRate = PubTool.ToDecimal(drRuleLineInfo[0]["ShipFeeRate"].ToString());
                decimal ShipFeeMny = PubTool.ToDecimal(drRuleLineInfo[0]["ShipFeeMny"].ToString());
                dto.TransportCost = (dto.ProductCost + dto.MarkCost) * ShipFeeRate + ShipFeeMny;
                #endregion

                #region 仓储费处理
                decimal WhFeeRate = PubTool.ToDecimal(drRuleLineInfo[0]["WhFeeRate"].ToString());
                decimal WhFeeMny = PubTool.ToDecimal(drRuleLineInfo[0]["WhFeeMny"].ToString());
                dto.StoreCost = (dto.ProductCost + dto.MarkCost) * WhFeeRate + WhFeeMny;
                #endregion

                #region 单价处理
                //经销商 20-经销商 21-办事处
                if (Context.LoginOrg.Code.StartsWith("2"))
                {
                    dto.Price = dto.ProductCost + dto.MarkCost + dto.TransportCost + dto.StoreCost;
                }
                //下线客户
                else if (cu.DescFlexField.PrivateDescSeg8 == "True")
                {
                    dto.Price = dto.ProductCost + dto.MarkCost + dto.TransportCost + dto.StoreCost;
                }
                //双虎组织不考虑仓储费
                else
                {
                    dto.Price = dto.ProductCost + dto.MarkCost + dto.TransportCost;
                }
                #endregion

            }
            
        }



        /// <summary>
        /// 批量获取将费用规则相关信息
        /// </summary>
        /// <param name="saleAgentOrgID">费用规则组织</param>
        /// <param name="itemIDList">参与取价的料品ID集合</param>
        /// <returns>费用规则相关信息</returns>
        public static DataTable GetFeeRuleByNeedSetPriceRecords(string saleAgentOrgID, List<string> itemIDList, string pricelistid)
        {
            string itemIDListParam = "itemIDList" + SysConstant.IDList_QueryParamSuffixName;
            string sql = "";
            sql = @"SELECT item.Code as ItemCode,
                       FeeRateSubLine.TransFeeRate as ShipFeeRate,
                       FeeRateSubLine.TransFee as ShipFeeMny,
                       FeeRateSubLine.WhseFeeRate as WhFeeRate,
                       FeeRateSubLine.WhseFee as WhFeeMny
                    --费用系数
                    FROM  Cust_FeeRate FeeRateSubLine    
                    --费用规则头 
                    join Cust_CBOPoRuleBE FeeRuleHead on FeeRuleHead.ID=FeeRateSubLine.CBOPoRuleBE
                    --料品              
                    join CBO_ItemMaster Item on Item.PriceCategory=FeeRateSubLine.ItemCatagory
                    where FeeRuleHead.Org={0}  
	                    and item.Code  in (@{1})
	                    and FeeRuleHead.SalePriceList={2}";
            sql = string.Format(sql, saleAgentOrgID, itemIDListParam, pricelistid);
            DataSet dsResult = null;
            DataParamList paramList = new DataParamList();
            paramList.Add(DataParamFactory.CreateInput(itemIDListParam, SysUtils.ToXml(SysUtils.CreateIDTable(itemIDList))));
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, paramList, string.Empty, true, out dsResult);
            if (dsResult != null && dsResult.Tables.Count > 0 && dsResult.Tables[0].Rows.Count > 0)
            {
                return dsResult.Tables[0];
            }
            return null;

        }

        /// <summary>
        /// 获取需要参与取价记录的销售价格信息(针对双虎销售订单，取客户价表价格)
        /// </summary>
        /// <param name="itemIDList">取价行料品ID集合</param>
        /// <param name="priceListID">价表ID</param>
        /// <param name="bizDate">销售订单业务日期</param>
        /// <returns>料品价格信息</returns>
        public DataTable GetItemPriceByNeedSetPriceRecords(List<long> itemIDList, long priceListID, DateTime bizDate,long custid)
        {
            string itemIDListParam = "ItemIDList" + SysConstant.IDList_QueryParamSuffixName;
            string strSql = "";

            strSql = @"SELECT pline.ItemInfo_ItemCode AS 料号,
                               phead.ID AS 双虎价表,
                               phead.Code AS 价表编码,   
                               pline.Price AS 销售价格,
                               pline.DescFlexField_PubDescSeg50 AS 正特价,
                               pline.DescFlexField_PubDescSeg42 AS 品牌费,
                               pline.Customer 客户ID
                        --销售价目表行
                        from SPR_SalePriceLine pline
                        --销售价目表头	
                        join SPR_SalePriceList phead ON pline.SalePriceList=phead.ID	
                        --价表ID
                        where phead.ID={0} 
                              --价表生效                 
                              and ('{1}' BETWEEN pline.FromDate AND pline.ToDate and pline.Active=1) 
                              and (pline.Customer is null or pline.Customer={2})
                              and pline.ItemInfo_ItemCode IN (
			                                                    SELECT item.Code FROM CBO_ItemMaster item
			                                                    WHERE item.ID in (@{3})
		                                                      )";
            strSql = string.Format(strSql, priceListID, bizDate, custid, itemIDListParam);
            DataSet dsResult = null;
            DataParamList paramList = new DataParamList();
            paramList.Add(DataParamFactory.CreateInput(itemIDListParam, SysUtils.ToXml(SysUtils.CreateIDTable(itemIDList))));
            DataAccessor.RunSQL(DataAccessor.GetConn(), strSql, paramList, string.Empty, true, out dsResult);
            if (dsResult != null && dsResult.Tables.Count > 0 && dsResult.Tables[0].Rows.Count > 0)
            {
                return dsResult.Tables[0];
            }
            return null;
        }

        /// <summary>
        /// 产品费+品牌费+物流费+仓储费
        ///（销售价目表取客户.私有6部门 - 经销商启用 - 双虎客户档案 - 价表；
        /// 费用规则 取 费用规则.双虎价表=销售价目表）
        /// </summary>
        /// <param name="orgid"></param>
        /// <param name="custormid"></param>
        /// <param name="bizdate"></param>
        /// <param name="itemids"></param>
        /// <returns></returns>
        private DataTable GetItemPriceByNeedSetPriceRecords1(long orgid, ref Customer cu, DateTime bizdate, List<long> itemids)
        {
            string itemIDListParam = "ItemIDList" + SysConstant.IDList_QueryParamSuffixName;
            string shorgid = "1001106046291924";
            string sql = "";
            DataSet priceds = new DataSet();

            string PricelistID = "";
            string CustID = "";

            sql = @"select cu.DescFlexField_PrivateDescSeg6 deptcode,agent.id agentid,cu1.PriceListID,cu1.ID CustID
                    --下线客户
                    from CBO_Customer cu
                    --部门
                    left join CBO_Department dept on dept.Code=cu.DescFlexField_PrivateDescSeg6 
	                    and dept.Org={0}
                    --进销商启用
                    left join Cust_CBO_SalesAgent agent on agent.Department=dept.ID
                    --双虎组织经销商
                    left join CBO_Customer cu1 on cu1.DefaultContact=agent.Contaction 
	                    and cu1.Org={1}
                    where cu.ID={2} and cu.Org={3}";
            sql = string.Format(sql, orgid, shorgid, cu.ID, orgid);
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, null, out priceds);
            if (priceds.Tables.Count <= 0 || priceds.Tables[0].Rows.Count <= 0)
            {
                throw new Exception("获取双虎组织价表失败!");
            }
            if (string.IsNullOrEmpty(priceds.Tables[0].Rows[0]["deptcode"].ToString()))
            {
                throw new Exception("客户私有扩展字段6[部门编码]为空!");
            }
            if (string.IsNullOrEmpty(priceds.Tables[0].Rows[0]["agentid"].ToString()))
            {
                throw new Exception("依据部门查找经销商启用失败!");
            }
            if (string.IsNullOrEmpty(priceds.Tables[0].Rows[0]["CustID"].ToString()))
            {
                throw new Exception("依据进销商启用，查找双虎组织客户失败!");
            }
            if (string.IsNullOrEmpty(priceds.Tables[0].Rows[0]["PriceListID"].ToString()))
            {
                throw new Exception("双虎组织客户价表为空!");
            }
            PricelistID = priceds.Tables[0].Rows[0]["PriceListID"].ToString();
            CustID = priceds.Tables[0].Rows[0]["CustID"].ToString();

            //if (PubTool.ToLong(CustID.ToString()) <= 0) throw new Exception("获取双虎组织经销商失败!");
            //if (PubTool.ToLong(PricelistID.ToString()) <= 0) throw new Exception("获取双虎组织价表失败!");

            cu = Customer.Finder.FindByID(PubTool.ToLong(CustID));
            if (cu == null) throw new Exception("获取双虎组织经销商失败!");

            sql = @"select pline.ItemInfo_ItemCode 料号,phead.ID 双虎价表,phead.Code 价格编码
	                ,pline.Price 销售价格
	                ,pline.DescFlexField_PubDescSeg50 正特价
	                ,pline.DescFlexField_PubDescSeg42 品牌费
                    ,pline.Customer 客户ID
                from SPR_SalePriceLine pline
                join SPR_SalePriceList phead on phead.ID=pline.SalePriceList
                where phead.ID={0}
                    and ('{1}' BETWEEN pline.FromDate AND pline.ToDate and pline.Active=1) 
                    and (pline.Customer is null or pline.Customer={2})
	                and pline.ItemInfo_ItemCode in 
	                (
		                select item.Code from CBO_ItemMaster item
		                where item.ID in (@{3})
                    )";
            sql = string.Format(sql, PricelistID, bizdate, CustID, itemIDListParam);
            DataSet dsResult = null;
            DataParamList paramList = new DataParamList();
            paramList.Add(DataParamFactory.CreateInput(itemIDListParam, SysUtils.ToXml(SysUtils.CreateIDTable(itemids))));
            DataAccessor.RunSQL(DataAccessor.GetConn(), sql, paramList, string.Empty, true, out dsResult);
            if (dsResult != null && dsResult.Tables.Count > 0 && dsResult.Tables[0].Rows.Count > 0)
            {
                return dsResult.Tables[0];
            }
            return null;
        }

        /// <summary>
        /// 批量获取料品的价格分类信息
        /// </summary>
        /// <param name="itemIDList">参与取价的料品ID集合</param>
        /// <returns>价格分类信息</returns>
        public static DataTable GetPriceCategoryInfos(List<long> itemIDList)
        {
            string itemIDListParam = "itemIDList" + SysConstant.IDList_QueryParamSuffixName;
            string strQrySql = string.Format(@"SELECT ItemLine.ID as ItemID,
                                                   ItemLine.PriceCategory as PriceCategory,
                                                   ItemCategory.Code as CategoryCode,
	                                               ItemCategory.DescFlexField_PrivateDescSeg1 as GetPriceStrategyCode
                                                FROM  CBO_ItemMaster ItemLine  --料品
                                                    LEFT JOIN CBO_Category ItemCategory on ItemLine.PriceCategory=ItemCategory.ID --料品分类
                                                WHERE ItemLine.ID in (@{0})", itemIDListParam);
            DataSet dsResult = null;
            DataParamList paramList = new DataParamList();
            paramList.Add(DataParamFactory.CreateInput(itemIDListParam, SysUtils.ToXml(SysUtils.CreateIDTable(itemIDList))));

            DataAccessor.RunSQL(DataAccessor.GetConn(), strQrySql, paramList, string.Empty, true, out dsResult);
            if (dsResult != null && dsResult.Tables.Count > 0 && dsResult.Tables[0].Rows.Count > 0)
            {
                return dsResult.Tables[0];
            }
            return null;

        }

        /// <summary>
        /// 获取需要参与取价记录的销售价格信息(针对总经销销售订单，双虎订单取客户价表价格)
        /// </summary>
        /// <param name="saleAgentOrgID">总代组织ID</param>
        /// <param name="isIncludeTax">销售订单价格是否含税</param>
        /// <param name="bizDate">销售订单业务日期</param>
        /// <param name="itemIDList">取价行料品ID集合</param>
        /// <returns>料品价格信息</returns>
//        public DataTable GetItemPriceByNeedSetPriceRecords(long saleAgentOrgID, int isIncludeTax, DateTime bizDate, List<long> itemIDList)
//        {
//            string itemIDListParam = "ItemIDList" + SysConstant.IDList_QueryParamSuffixName;
//            string strSql = string.Format(@"SELECT line.ItemMaster_ItemCode AS 料号,
//	                                               head.SalePriceList AS 双虎价表,
//                                                   phead.Code AS 价表编码,   
//	                                               pline.Price AS 销售价格,
//	                                               pline.DescFlexField_PubDescSeg50 AS 正特价	   
//                                            FROM Cust_PORuleItemFee line		--费用规则行
//                                                LEFT JOIN Cust_CBOPoRuleBE head ON line.CBOPoRuleBE=head.ID		--费用规则头
//                                                LEFT JOIN SPR_SalePriceLine pline ON line.ItemMaster_ItemCode=pline.ItemInfo_ItemCode	--销售价目表行
//                                                LEFT JOIN SPR_SalePriceList phead ON head.SalePriceList=phead.ID	--销售价目表头
//                                            WHERE head.Org={0}
//	                                              AND pline.SalePriceList=head.SalePriceList
//	                                              AND ('{1}' BETWEEN pline.FromDate AND pline.ToDate and pline.Active=1) --价表生效
//	                                              AND phead.IsIncludeTax={2}	--价表是否含税 
//	                                              AND line.ItemMaster_ItemCode IN (
//										                                            SELECT item.Code FROM CBO_ItemMaster item
//										                                            WHERE item.ID in (@{3})
//									                                              )", saleAgentOrgID, bizDate, isIncludeTax, itemIDListParam);
//            DataSet dsResult = null;
//            DataParamList paramList = new DataParamList();
//            paramList.Add(DataParamFactory.CreateInput(itemIDListParam, SysUtils.ToXml(SysUtils.CreateIDTable(itemIDList))));
//            DataAccessor.RunSQL(DataAccessor.GetConn(), strSql, paramList, string.Empty, true, out dsResult);
//            if (dsResult != null && dsResult.Tables.Count > 0 && dsResult.Tables[0].Rows.Count > 0)
//            {
//                return dsResult.Tables[0];
//            }
//            return null;
//        }
    }

	#endregion
	
	
}